/*
 * NodoB.cpp
 *
 *  Created on: 08/11/2011
 *      Author: agustin
 */

#include "NodoB.h"

NodoB::NodoB() {
	this->cant_datos = 0;
	this->extra = NULL;
	this->datos = new reg_arbolB[tam_nodo];
	this->hijos = new NodoB*[tam_nodo + 1];

	for(size_t i = 0; i <= tam_nodo; i++) {
		this->hijos[i] = NULL;
	}
}

NodoB::~NodoB() {
	delete[] datos;
	for (size_t i = 0; i <= tam_nodo; i++) {
		if (this->hijos[i] != NULL) {
			delete this->hijos[i];
		}
	}
	delete[] hijos;
}

bool NodoB::estaLleno() {
	return !(cant_datos < tam_nodo);
}

int NodoB::addDato(reg_arbolB* dato) {
	if (!this->estaLleno()) {
		datos[cant_datos] = *dato;
		cant_datos++;
		delete dato;
		return 0;
	} else if (extra == NULL) {
		extra = dato;
		return 0;
	}
	return -1;
}

void NodoB::setExtra(reg_arbolB* dato) {
	this->extra = dato;
}

reg_arbolB* NodoB::getExtra() {
	return this->extra;
}

void NodoB::setHijo(NodoB* hijo, size_t pos) {
	if (pos <= this->tam_nodo) {
		this->hijos[pos] = hijo;
	}
}

NodoB* NodoB::getHijo(size_t pos) {
	if (pos <= this->tam_nodo) {
		return this->hijos[pos];
	}
	return NULL;
}

size_t NodoB::getTam() {
	return this->tam_nodo;
}

bool NodoB::tieneExtra() {
	return extra != NULL;
}

void NodoB::print() {
	for (size_t i = 0; i < this->cant_datos; i++) {
		if (hijos[i] != NULL) {
			hijos[i]->print();
			cout << datos[i].termino << " - " << datos[i].posicion << endl;
		} else {
			cout << datos[i].termino << " - " << datos[i].posicion << endl;
		}
	}
	if (hijos[cant_datos] != NULL) {
		hijos[cant_datos]->print();
	}
}

bool NodoB::esHoja() {
	return hijos[0] == NULL;
}

int NodoB::buscar(string termino) {
//Devuelve el bloque de front coding donde puede o no estar ubicado el termino

//Menor al primer dato
	if (termino < datos[0].termino) {
		if (hijos[0] != NULL) {
			return hijos[0]->buscar(termino);
		} else {
			return -1;
		}
	}

	//Intermedios
	for (size_t i = 0; i < cant_datos - 1; i++) {
		if (termino == datos[i].termino) {
			//lo encontro
			return datos[i].posicion;
		} else if (termino > datos[i].termino && termino < datos[i + 1].termino) {
			if (hijos[i + 1] != NULL) {
				int pos = hijos[i + 1]->buscar(termino);
				if (pos == -1) {
					return datos[i].posicion;
				} else {
					return pos;
				}
			} else {
				return datos[i].posicion;
			}
		}
	}

	//Mayor igual al ultimo dato
	if (termino == datos[cant_datos - 1].termino) {
		//lo encontro
		return datos[cant_datos - 1].posicion;
	} else if (termino > datos[cant_datos - 1].termino) {
		if (hijos[cant_datos] != NULL) {
			int pos = hijos[cant_datos]->buscar(termino);
			if (pos == -1) {
				return datos[cant_datos-1].posicion;
			} else {
				return pos;
			}
		} else {
			return datos[cant_datos-1].posicion;
		}
	}
	return -2;
}
